using Microsoft.Web.Administration;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net.Http;
using System.ServiceProcess;
using System.Threading.Tasks;

public class UpdateManager
{
    private readonly string configPath = "config.json";
    private readonly string versionsPath = "versions.json";
    private Config config;
    private Dictionary<string, List<VersionInfo>> versions;
    private IISCollector iisCollector;

    public UpdateManager()
    {
        try
        {
            LoadConfig();
            LoadVersions();
            iisCollector = new IISCollector();
        }
        catch (Exception ex)
        {
            Logger.LogError("UpdateManager初始化失败", ex);
            throw;
        }
    }

    public List<Product> GetProducts() => config.Products;

    public async Task<bool> UpdateProduct(string productId, string version, IProgress<string> progress)
    {
        var product = config.Products.FirstOrDefault(p => p.Id == productId);
        if (product == null)
        {
            progress.Report("产品不存在");
            return false;
        }

        try
        {
            progress.Report($"开始更新 {product.Name} 到版本 {version}");
            
            progress.Report("创建备份...");
            await CreateBackup(product).ConfigureAwait(false);
            
            progress.Report("停止服务...");
            await StopService(product).ConfigureAwait(false);
            await Task.Delay(2000).ConfigureAwait(false);
            
            progress.Report("下载新版本...");
            var downloadUrl = await GetVersionDownloadUrl(product.ProductName, version).ConfigureAwait(false);
            if (string.IsNullOrEmpty(downloadUrl))
            {
                throw new Exception("未找到版本下载地址");
            }
            
            await DownloadAndExtractVersion(downloadUrl, product.Path, progress).ConfigureAwait(false);
            
            progress.Report("部署完成，准备启动服务...");
            await Task.Delay(2000).ConfigureAwait(false);
            
            progress.Report("启动服务...");
            await StartService(product).ConfigureAwait(false);
            await Task.Delay(1000).ConfigureAwait(false);
            
            UpdateVersionRecord(productId, version, product.Path);
            product.CurrentVersion = version;
            SaveConfig();
            
            progress.Report("更新完成");
            return true;
        }
        catch (Exception ex)
        {
            Logger.LogError($"产品更新失败 - {product.Name}", ex);
            progress.Report($"更新失败: {ex.Message}");
            
            try
            {
                progress.Report("尝试重启服务...");
                await StartService(product).ConfigureAwait(false);
            }
            catch { }
            
            return false;
        }
    }

    public async Task<bool> RollbackProduct(string productId, string version, IProgress<string> progress)
    {
        var product = config.Products.FirstOrDefault(p => p.Id == productId);
        if (product == null) return false;

        try
        {
            progress.Report($"开始回滚 {product.Name} 到版本 {version}");
            
            await StopService(product);
            progress.Report("恢复备份文件...");
            await Task.Delay(1500);
            await StartService(product);
            
            UpdateVersionRecord(productId, version, product.Path);
            product.CurrentVersion = version;
            SaveConfig();
            
            progress.Report("回滚完成");
            return true;
        }
        catch (Exception ex)
        {
            progress.Report($"回滚失败: {ex.Message}");
            return false;
        }
    }

    public List<VersionInfo> GetVersionHistory(string productId)
    {
        return versions.ContainsKey(productId) ? versions[productId] : new List<VersionInfo>();
    }

    public List<string> GetAvailableVersions(string productId)
    {
        var availableVersions = new List<string> { "1.0.1", "1.0.2", "1.1.0", "1.2.0", "2.0.0" };
        
        // 添加历史版本用于回滚
        var historyVersions = GetVersionHistory(productId)
            .Select(v => v.Version)
            .Where(v => !availableVersions.Contains(v))
            .Distinct();
        
        availableVersions.AddRange(historyVersions);
        return availableVersions.OrderByDescending(v => v).ToList();
    }

    public async Task<List<IISServiceInfo>> CollectIISServices(IProgress<string> progress)
    {
        return await iisCollector.CollectIISServices(progress);
    }

    public List<IISServiceInfo> GetStoredIISServices()
    {
        return iisCollector.GetStoredServices();
    }

    public void AddProduct(Product product)
    {
        config.Products.Add(product);
        iisCollector.SaveProduct(product);
        SaveConfig();
    }
    
    public void LoadProductsFromDatabase()
    {
        config.Products = iisCollector.LoadProducts();
        SaveConfig();
    }
    
    public async Task<bool> DeployIISService(string siteName, string sourcePath, string targetPath, int port, IProgress<string> progress)
    {
        try
        {
            progress.Report($"开始部署IIS服务: {siteName}");
            
            // 检查管理员权限
            if (!IsRunningAsAdministrator())
            {
                throw new UnauthorizedAccessException("需要管理员权限才能部署IIS服务。请以管理员身份运行程序。");
            }
            
            // 复制文件
            progress.Report("复制文件到目标路径...");
            if (Directory.Exists(sourcePath))
            {
                await CopyDirectory(sourcePath, targetPath);
            }
            else if (File.Exists(sourcePath))
            {
                Directory.CreateDirectory(targetPath);
                await Task.Run(() => File.Copy(sourcePath, Path.Combine(targetPath, Path.GetFileName(sourcePath)), true));
            }
            
            // 创建IIS站点
            progress.Report("创建IIS站点...");
            using var serverManager = new ServerManager();
            
            // 检查站点是否已存在
            var existingSite = serverManager.Sites.FirstOrDefault(s => s.Name == siteName);
            if (existingSite != null)
            {
                serverManager.Sites.Remove(existingSite);
            }
            
            // 创建新站点
            var site = serverManager.Sites.Add(siteName, targetPath, port);
            serverManager.CommitChanges();
            
            progress.Report($"IIS服务部署完成: {siteName}:{port}");
            return true;
        }
        catch (UnauthorizedAccessException ex)
        {
            progress.Report($"权限错误: {ex.Message}");
            throw;
        }
        catch (Exception ex)
        {
            progress.Report($"部署失败: {ex.Message}");
            return false;
        }
    }
    
    private async Task CopyDirectory(string sourceDir, string targetDir)
    {
        Directory.CreateDirectory(targetDir);
        
        foreach (var file in Directory.GetFiles(sourceDir))
        {
            var targetFile = Path.Combine(targetDir, Path.GetFileName(file));
            await Task.Run(() => File.Copy(file, targetFile, true));
        }
        
        foreach (var dir in Directory.GetDirectories(sourceDir))
        {
            var targetSubDir = Path.Combine(targetDir, Path.GetFileName(dir));
            await CopyDirectory(dir, targetSubDir);
        }
    }

    public void UpdateIISServiceInfo(string siteName, string productName, string version)
    {
        iisCollector.UpdateServiceInfo(siteName, productName, version);
    }
    
    public void DeleteProduct(string productId)
    {
        var product = config.Products.FirstOrDefault(p => p.Id == productId);
        if (product != null)
        {
            config.Products.Remove(product);
            iisCollector.DeleteProduct(productId);
            SaveConfig();
        }
    }
    
    public void UpdateProduct(Product product)
    {
        var existingProduct = config.Products.FirstOrDefault(p => p.Id == product.Id);
        if (existingProduct != null)
        {
            existingProduct.ProductName = product.ProductName;
            existingProduct.CurrentVersion = product.CurrentVersion;
            iisCollector.SaveProduct(existingProduct);
            SaveConfig();
        }
    }
    
    public async Task<List<string>> GetProductsFromAPI(string deployType = "")
    {
        try
        {
            using var client = new HttpClient();
            client.BaseAddress = new Uri(config.UpdateServer);
            var url = string.IsNullOrEmpty(deployType) ? "/api/Api/products" : $"/api/Api/products?type={deployType}";
            var response = await client.GetAsync(url);
            if (response.IsSuccessStatusCode)
            {
                var json = await response.Content.ReadAsStringAsync();
                return JsonConvert.DeserializeObject<List<string>>(json) ?? new List<string>();
            }
        }
        catch
        {
            // 如果API调用失败，返回默认列表
        }
        return new List<string> { "产品A", "产品B", "产品C", "产品D" };
    }
    
    public async Task<List<string>> GetVersionsFromAPI(string productName)
    {
        try
        {
            using var client = new HttpClient();
            client.BaseAddress = new Uri(config.UpdateServer);
            var response = await client.GetAsync($"/api/Api/versions/{Uri.EscapeDataString(productName)}");
            if (response.IsSuccessStatusCode)
            {
                var json = await response.Content.ReadAsStringAsync();
                var versionData = JsonConvert.DeserializeObject<List<ApiVersionInfo>>(json);
                return versionData?.Select(v => v.Version).ToList() ?? new List<string>();
            }
        }
        catch
        {
            // 如果API调用失败，返回默认版本
        }
        return new List<string> { "1.0.0", "1.0.1", "1.1.0" };
    }

    public async Task<string?> GetVersionDownloadUrl(string productName, string version)
    {
        try
        {
            using var client = new HttpClient();
            client.BaseAddress = new Uri(config.UpdateServer);
            var response = await client.GetAsync($"/api/Api/versions/{Uri.EscapeDataString(productName)}");
            if (response.IsSuccessStatusCode)
            {
                var json = await response.Content.ReadAsStringAsync();
                var versionData = JsonConvert.DeserializeObject<List<ApiVersionInfo>>(json);
                var versionInfo = versionData?.FirstOrDefault(v => v.Version == version);
                if (!string.IsNullOrEmpty(versionInfo?.FilePath))
                {
                    return versionInfo.FilePath.StartsWith("http") ? versionInfo.FilePath : $"{config.DownloadBaseUrl}{versionInfo.FilePath}";
                }
            }
        }
        catch
        {
            // API调用失败，使用配置文件中的固定地址
        }
        return config.DownloadBaseUrl;
    }

    public string GetServerUrl()
    {
        return config.UpdateServer;
    }
    
    public string GetDownloadBaseUrl()
    {
        return config.DownloadBaseUrl;
    }
    
    public string GetServiceDownloadUrl()
    {
        return config.ServiceDownloadUrl;
    }

    public async Task<bool> DeployIISServiceFromUrl(string siteName, string downloadUrl, string targetPath, int port, IProgress<string> progress)
    {
        try
        {
            progress.Report($"开始部署IIS服务: {siteName}");
            
            // 检查管理员权限
            if (!IsRunningAsAdministrator())
            {
                throw new UnauthorizedAccessException("需要管理员权限才能部署IIS服务。请以管理员身份运行程序。");
            }
            
            // 检查站点名称和端口冲突
            using var checkManager = new ServerManager();
            var existingSite = checkManager.Sites.FirstOrDefault(s => s.Name == siteName);
            if (existingSite != null)
            {
                throw new Exception($"站点名称 '{siteName}' 已存在");
            }
            
            var existingPort = checkManager.Sites.Any(s => s.Bindings.Any(b => b.EndPoint?.Port == port));
            if (existingPort)
            {
                throw new Exception($"端口 {port} 已被占用");
            }
            
            // 下载文件
            using var client = new HttpClient();
            var response = await client.GetAsync(downloadUrl, HttpCompletionOption.ResponseHeadersRead);
            if (!response.IsSuccessStatusCode)
            {
                throw new Exception($"下载失败: {response.StatusCode}");
            }
            
            var totalBytes = response.Content.Headers.ContentLength ?? 0;
            var tempFile = Path.GetTempFileName() + ".zip";
            
            await using var contentStream = await response.Content.ReadAsStreamAsync();
            await using var fileStream = File.Create(tempFile);
            
            var buffer = new byte[8192];
            var totalRead = 0L;
            int bytesRead;
            
            while ((bytesRead = await contentStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
            {
                await fileStream.WriteAsync(buffer, 0, bytesRead);
                totalRead += bytesRead;
                
                if (totalBytes > 0)
                {
                    var percentage = (int)((totalRead * 100) / totalBytes);
                    progress.Report($"下载进度: {percentage}% ({totalRead / 1024 / 1024:F1}MB/{totalBytes / 1024 / 1024:F1}MB)");
                }
                else
                {
                    progress.Report($"已下载: {totalRead / 1024 / 1024:F1}MB");
                }
            }
            
            fileStream.Close();
            progress.Report("下载完成，开始解压...");
            
            // 解压文件到网站名称+端口文件夹
            var wupayPath = Path.Combine(targetPath, $"{siteName}_{port}");
            if (Directory.Exists(wupayPath))
            {
                Directory.Delete(wupayPath, true);
            }
            Directory.CreateDirectory(targetPath);
            Directory.CreateDirectory(wupayPath);
            ZipFile.ExtractToDirectory(tempFile, wupayPath);
            
            // 创建IIS站点
            progress.Report("创建IIS站点...");
            using var serverManager = new ServerManager();
            var site = serverManager.Sites.Add(siteName, wupayPath, port);
            serverManager.CommitChanges();
            
            // 清理临时文件
            File.Delete(tempFile);
            
            progress.Report($"IIS服务部署完成: {siteName}:{port}");
            return true;
        }
        catch (UnauthorizedAccessException ex)
        {
            progress.Report($"权限错误: {ex.Message}");
            throw;
        }
        catch (Exception ex)
        {
            progress.Report($"部署失败: {ex.Message}");
            throw;
        }
    }
    
    public async Task GenerateAppConfig(Product product, string version)
    {
        if (string.IsNullOrEmpty(product.Path)) return;
        
        var configPath = Path.Combine(product.Path, "app.config.json");
        var appConfig = new
        {
            Version = version,
            ProductName = product.ProductName
        };
        
        var json = JsonConvert.SerializeObject(appConfig, Formatting.Indented);
        await File.WriteAllTextAsync(configPath, json);
    }
    
    private string GetLocalIpAddress()
    {
        try
        {
            // 检查是否为服务器系统
            var osInfo = Environment.OSVersion;
            var isServer = osInfo.Platform == PlatformID.Win32NT && 
                          (osInfo.Version.Major >= 6 && 
                           (Environment.OSVersion.ToString().Contains("Server") || 
                            System.IO.File.Exists(@"C:\Windows\System32\ServerManager.exe")));
            
            if (isServer)
            {
                // 服务器系统：获取公网IP
                using var client = new HttpClient();
                client.Timeout = TimeSpan.FromSeconds(5);
                var publicIp = client.GetStringAsync("https://api.ipify.org").Result.Trim();
                return publicIp;
            }
            else
            {
                // 非服务器系统：获取内网IP
                var host = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName());
                foreach (var ip in host.AddressList)
                {
                    if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork && 
                        !System.Net.IPAddress.IsLoopback(ip))
                    {
                        return ip.ToString();
                    }
                }
            }
        }
        catch
        {
            // 如果获取失败，返回默认IP
        }
        
        return "127.0.0.1";
    }
    
    private async Task InstallAndStartWindowsService(string serviceName, string servicePath, IProgress<string> progress)
    {
        try
        {
            // 查找服务可执行文件
            var exeFiles = Directory.GetFiles(servicePath, "*.exe", SearchOption.AllDirectories)
                .Where(f => !Path.GetFileName(f).StartsWith("dotnet", StringComparison.OrdinalIgnoreCase))
                .ToArray();
            
            if (exeFiles.Length == 0)
            {
                progress.Report("未找到服务可执行文件，跳过自动安装");
                return;
            }
            
            var serviceExe = exeFiles[0];
            progress.Report($"找到服务文件: {Path.GetFileName(serviceExe)}");
            
            // 安装服务
            progress.Report("正在安装Windows服务...");
            var installArgs = $"create {serviceName} binPath= \"{serviceExe}\" start= auto";
            var installResult = await RunCommand("sc", installArgs);
            
            if (installResult.Contains("SUCCESS") || installResult.Contains("成功"))
            {
                progress.Report("服务安装成功");
                
                // 启动服务
                progress.Report("正在启动服务...");
                var startArgs = $"start {serviceName}";
                var startResult = await RunCommand("sc", startArgs);
                
                if (startResult.Contains("SUCCESS") || startResult.Contains("成功"))
                {
                    progress.Report("服务启动成功");
                }
                else
                {
                    progress.Report($"服务启动失败: {startResult}");
                }
            }
            else
            {
                progress.Report($"服务安装失败: {installResult}");
            }
        }
        catch (Exception ex)
        {
            progress.Report($"自动安装服务失败: {ex.Message}");
        }
    }
    
    private async Task<string> RunCommand(string command, string arguments)
    {
        try
        {
            var processInfo = new ProcessStartInfo
            {
                FileName = command,
                Arguments = arguments,
                RedirectStandardOutput = true,
                RedirectStandardError = true,
                UseShellExecute = false,
                CreateNoWindow = true
            };
            
            using var process = Process.Start(processInfo);
            if (process != null)
            {
                var output = await process.StandardOutput.ReadToEndAsync();
                var error = await process.StandardError.ReadToEndAsync();
                await process.WaitForExitAsync();
                
                return string.IsNullOrEmpty(error) ? output : error;
            }
        }
        catch (Exception ex)
        {
            return $"Command execution failed: {ex.Message}";
        }
        
        return "Command execution failed";
    }
    
    public async Task<string?> GetLatestVersion(string productName)
    {
        try
        {
            var versions = await GetVersionsFromAPI(productName);
            return versions.FirstOrDefault();
        }
        catch
        {
            return null;
        }
    }
    
    public async Task<bool> UpdateAutoUpdater(string version, IProgress<string> progress)
    {
        try
        {
            progress.Report($"开始更新AutoUpdater到版本 {version}");
            
            var downloadUrl = await GetVersionDownloadUrl("AutoUpdater", version);
            if (string.IsNullOrEmpty(downloadUrl))
            {
                throw new Exception("未找到版本下载地址");
            }
            
            var currentPath = AppDomain.CurrentDomain.BaseDirectory;
            var tempUpdatePath = Path.Combine(Path.GetTempPath(), "AutoUpdater_Update_" + Guid.NewGuid().ToString("N"));
            Directory.CreateDirectory(tempUpdatePath);
            
            progress.Report("下载新版本...");
            await DownloadAndExtractVersion(downloadUrl, tempUpdatePath, progress);
            
            progress.Report("创建更新脚本...");
            var batchFile = Path.Combine(Path.GetTempPath(), "update_autoupdater.bat");
            var backupFolder = $"backup_{DateTime.Now:yyyyMMddHHmmss}";
            var exePath = Path.Combine(currentPath, "AutoUpdater.exe");
            var batchContent = "@echo off" + Environment.NewLine +
                "title AutoUpdater Update" + Environment.NewLine +
                "color 0A" + Environment.NewLine +
                "echo ========================================" + Environment.NewLine +
                "echo    AutoUpdater Auto Update" + Environment.NewLine +
                "echo ========================================" + Environment.NewLine +
                "echo." + Environment.NewLine +
                "echo Waiting for program to close..." + Environment.NewLine +
                "timeout /t 3 /nobreak" + Environment.NewLine +
                "echo." + Environment.NewLine +
                "echo Backing up current version..." + Environment.NewLine +
                $"if not exist \"{currentPath}{backupFolder}\" mkdir \"{currentPath}{backupFolder}\"" + Environment.NewLine +
                "echo Backup complete" + Environment.NewLine +
                "echo." + Environment.NewLine +
                "echo Copying new files..." + Environment.NewLine +
                $"xcopy /Y /E /I /Q \"{tempUpdatePath}\\*\" \"{currentPath}\"" + Environment.NewLine +
                "echo Files copied" + Environment.NewLine +
                "echo." + Environment.NewLine +
                "echo Cleaning temp files..." + Environment.NewLine +
                $"rd /s /q \"{tempUpdatePath}\"" + Environment.NewLine +
                "echo Cleanup complete" + Environment.NewLine +
                "echo." + Environment.NewLine +
                "echo Update complete! Restarting in 3 seconds..." + Environment.NewLine +
                "timeout /t 3 /nobreak" + Environment.NewLine +
                $"cd /d \"{currentPath}\"" + Environment.NewLine +
                $"start \"\" \"{exePath}\"" + Environment.NewLine +
                "del \"%~f0\"" + Environment.NewLine +
                "exit";
            
            await File.WriteAllTextAsync(batchFile, batchContent, System.Text.Encoding.Default);
            await RecordUpdateInfo(version);
            
            progress.Report("启动更新脚本并关闭程序...");
            Process.Start(new ProcessStartInfo
            {
                FileName = batchFile,
                UseShellExecute = true,
                CreateNoWindow = false
            });
            
            await Task.Delay(500);
            Environment.Exit(0);
            return true;
        }
        catch (Exception ex)
        {
            progress.Report($"更新失败: {ex.Message}");
            return false;
        }
    }
    
    public async Task<bool> DeployWindowsServiceFromUrl(string serviceName, string downloadUrl, string targetPath, IProgress<string> progress)
    {
        try
        {
            progress.Report($"开始部署Windows服务: {serviceName}");
            
            // 检查服务名称是否已存在
            var existingService = ServiceController.GetServices().FirstOrDefault(s => s.ServiceName == serviceName);
            if (existingService != null)
            {
                throw new Exception($"服务名称 '{serviceName}' 已存在");
            }
            
            // 下载文件
            using var client = new HttpClient();
            var response = await client.GetAsync(downloadUrl, HttpCompletionOption.ResponseHeadersRead);
            if (!response.IsSuccessStatusCode)
            {
                throw new Exception($"下载失败: {response.StatusCode}");
            }
            
            var totalBytes = response.Content.Headers.ContentLength ?? 0;
            var tempFile = Path.GetTempFileName() + ".zip";
            
            await using var contentStream = await response.Content.ReadAsStreamAsync();
            await using var fileStream = File.Create(tempFile);
            
            var buffer = new byte[8192];
            var totalRead = 0L;
            int bytesRead;
            
            while ((bytesRead = await contentStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
            {
                await fileStream.WriteAsync(buffer, 0, bytesRead);
                totalRead += bytesRead;
                
                if (totalBytes > 0)
                {
                    var percentage = (int)((totalRead * 100) / totalBytes);
                    progress.Report($"下载进度: {percentage}% ({totalRead / 1024 / 1024:F1}MB/{totalBytes / 1024 / 1024:F1}MB)");
                }
                else
                {
                    progress.Report($"已下载: {totalRead / 1024 / 1024:F1}MB");
                }
            }
            
            fileStream.Close();
            progress.Report("下载完成，开始解压...");
            
            // 解压文件到server+服务名称文件夹
            var serverPath = Path.Combine(targetPath, $"server{serviceName}");
            if (Directory.Exists(serverPath))
            {
                Directory.Delete(serverPath, true);
            }
            Directory.CreateDirectory(targetPath);
            Directory.CreateDirectory(serverPath);
            ZipFile.ExtractToDirectory(tempFile, serverPath);
            
            // 清理临时文件
            File.Delete(tempFile);
            
            progress.Report($"Windows服务部署完成: {serviceName}");
            
            // 自动安装和启动服务
            await InstallAndStartWindowsService(serviceName, serverPath, progress);
            
            return true;
        }
        catch (Exception ex)
        {
            progress.Report($"部署失败: {ex.Message}");
            throw;
        }
    }
    
    public async Task<bool> SyncProductToServer(Product product)
    {
        try
        {
            using var client = new HttpClient();
            client.BaseAddress = new Uri(config.UpdateServer);
            
            var deployedApp = new
            {
                ServiceName = product.Type == "iis" ? product.SiteName : product.ServiceName,
                ProductName = product.ProductName,
                Version = product.CurrentVersion,
                DeployPath = product.Path,
                SystemType = product.Type.ToUpper(),
                IsEnabled = true,
                EnterpriseCode = config.EnterpriseCode,
                ServerIp = GetLocalIpAddress()
            };
            
            var json = JsonConvert.SerializeObject(deployedApp);
            var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");
            
            var response = await client.PostAsync("/api/Api/deployed-applications", content);
            return response.IsSuccessStatusCode;
        }
        catch
        {
            return false;
        }
    }

    private async Task CreateBackup(Product product)
    {
        try
        {
            if (!Directory.Exists(product.Path)) return;
            
            // 在运行目录下创建备份文件夹
            var backupPath = Path.Combine(product.Path, "backup_" + DateTime.Now.ToString("yyyyMMddHHmmss"));
            Directory.CreateDirectory(backupPath);
            
            // 备份当前目录下的所有文件（除了备份文件夹）
            foreach (var file in Directory.GetFiles(product.Path))
            {
                var fileName = Path.GetFileName(file);
                await Task.Run(() => File.Copy(file, Path.Combine(backupPath, fileName), true));
            }
            
            foreach (var dir in Directory.GetDirectories(product.Path))
            {
                var dirName = Path.GetFileName(dir);
                if (!dirName.StartsWith("backup_") && !dirName.ToLower().Contains("log"))
                {
                    await CopyDirectory(dir, Path.Combine(backupPath, dirName));
                }
            }
        }
        catch (Exception ex)
        {
            throw new Exception($"备份失败: {ex.Message}");
        }
    }

    private async Task StopService(Product product)
    {
        if (product.Type == "service" && !string.IsNullOrEmpty(product.ServiceName))
        {
            try
            {
                using var service = new ServiceController(product.ServiceName);
                if (service.Status == ServiceControllerStatus.Running)
                {
                    service.Stop();
                    service.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(30));
                }
            }
            catch (Exception ex)
            {
                throw new Exception($"停止服务失败: {ex.Message}");
            }
        }
        else if (product.Type == "iis" && !string.IsNullOrEmpty(product.SiteName))
        {
            try
            {
                using var serverManager = new ServerManager();
                var site = serverManager.Sites.FirstOrDefault(s => s.Name == product.SiteName);
                if (site != null && site.State == ObjectState.Started)
                {
                    site.Stop();
                }
            }
            catch (Exception ex)
            {
                throw new Exception($"停止IIS站点失败: {ex.Message}");
            }
        }
    }

    private async Task StartService(Product product)
    {
        if (product.Type == "service" && !string.IsNullOrEmpty(product.ServiceName))
        {
            try
            {
                using var service = new ServiceController(product.ServiceName);
                if (service.Status == ServiceControllerStatus.Stopped)
                {
                    service.Start();
                    service.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(30));
                }
            }
            catch (Exception ex)
            {
                throw new Exception($"启动服务失败: {ex.Message}");
            }
        }
        else if (product.Type == "iis" && !string.IsNullOrEmpty(product.SiteName))
        {
            try
            {
                using var serverManager = new ServerManager();
                var site = serverManager.Sites.FirstOrDefault(s => s.Name == product.SiteName);
                if (site != null && site.State == ObjectState.Stopped)
                {
                    site.Start();
                }
            }
            catch (Exception ex)
            {
                throw new Exception($"启动IIS站点失败: {ex.Message}");
            }
        }
    }

    private void UpdateVersionRecord(string productId, string version, string path)
    {
        if (!versions.ContainsKey(productId))
            versions[productId] = new List<VersionInfo>();

        versions[productId].Add(new VersionInfo
        {
            Version = version,
            DeployTime = DateTime.Now,
            DeployPath = path,
            Status = "Active"
        });

        SaveVersions();
    }

    private void LoadConfig()
    {
        if (File.Exists(configPath))
        {
            var json = File.ReadAllText(configPath);
            config = JsonConvert.DeserializeObject<Config>(json) ?? new Config();
        }
        else
        {
            config = CreateDefaultConfig();
            SaveConfig();
        }
    }

    private void LoadVersions()
    {
        if (File.Exists(versionsPath))
        {
            var json = File.ReadAllText(versionsPath);
            versions = JsonConvert.DeserializeObject<Dictionary<string, List<VersionInfo>>>(json) ?? new();
        }
        else
        {
            versions = new Dictionary<string, List<VersionInfo>>();
        }
    }

    private void SaveConfig()
    {
        var json = JsonConvert.SerializeObject(config, Formatting.Indented);
        File.WriteAllText(configPath, json);
    }

    private void SaveVersions()
    {
        var json = JsonConvert.SerializeObject(versions, Formatting.Indented);
        File.WriteAllText(versionsPath, json);
    }

    private async Task DownloadAndExtractVersion(string downloadUrl, string targetPath, IProgress<string> progress)
    {
        string tempFile = "";
        string tempExtractPath = "";
        
        try
        {
            Logger.LogError($"开始下载: {downloadUrl}", null);
            progress.Report("开始下载文件...");
            
            using (var client = new HttpClient())
            {
                client.Timeout = TimeSpan.FromMinutes(30);
                
                var response = await client.GetAsync(downloadUrl, HttpCompletionOption.ResponseHeadersRead);
                
                if (!response.IsSuccessStatusCode)
                {
                    throw new Exception($"下载失败: {response.StatusCode}");
                }
                
                var totalBytes = response.Content.Headers.ContentLength ?? 0;
                tempFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".zip");
                
                Logger.LogError($"临时文件: {tempFile}, 总大小: {totalBytes} 字节", null);
                
                long totalRead = 0L;
                
                using (var contentStream = await response.Content.ReadAsStreamAsync())
                using (var fileStream = new FileStream(tempFile, FileMode.Create, FileAccess.Write, FileShare.None))
                {
                    var buffer = new byte[81920];
                    int bytesRead;
                    var lastReport = 0;
                    
                    while ((bytesRead = await contentStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
                    {
                        await fileStream.WriteAsync(buffer, 0, bytesRead);
                        totalRead += bytesRead;
                        
                        if (totalBytes > 0)
                        {
                            var percentage = (int)((totalRead * 100) / totalBytes);
                            if (percentage - lastReport >= 5)
                            {
                                progress.Report($"下载进度: {percentage}%");
                                lastReport = percentage;
                            }
                        }
                    }
                    
                    await fileStream.FlushAsync();
                }
                
                Logger.LogError($"下载完成: {totalRead} 字节", null);
            }
            
            progress.Report("下载完成，开始解压...");
            
            tempExtractPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(tempExtractPath);
            
            await Task.Run(() => 
            {
                ZipFile.ExtractToDirectory(tempFile, tempExtractPath);
            });
            
            Logger.LogError("解压完成", null);
            progress.Report("解压完成，开始替换文件...");
            
            await ReplaceFiles(tempExtractPath, targetPath, progress);
            
            progress.Report("文件替换完成");
            Logger.LogError("更新流程完成", null);
        }
        catch (Exception ex)
        {
            Logger.LogError("下载解压失败", ex);
            progress.Report($"下载解压失败: {ex.Message}");
            throw;
        }
        finally
        {
            try
            {
                if (!string.IsNullOrEmpty(tempFile) && File.Exists(tempFile))
                {
                    File.Delete(tempFile);
                    Logger.LogError($"删除临时文件: {tempFile}", null);
                }
                    
                if (!string.IsNullOrEmpty(tempExtractPath) && Directory.Exists(tempExtractPath))
                {
                    Directory.Delete(tempExtractPath, true);
                    Logger.LogError($"删除临时目录: {tempExtractPath}", null);
                }
            }
            catch (Exception ex)
            {
                Logger.LogError("清理临时文件失败", ex);
            }
        }
    }

    private async Task ReplaceFiles(string sourcePath, string targetPath, IProgress<string> progress)
    {
        await Task.Run(() =>
        {
            if (!Directory.Exists(targetPath))
            {
                Directory.CreateDirectory(targetPath);
            }
            
            progress.Report("开始替换文件...");
            
            var files = Directory.GetFiles(sourcePath, "*", SearchOption.AllDirectories);
            for (int i = 0; i < files.Length; i++)
            {
                var file = files[i];
                var relativePath = Path.GetRelativePath(sourcePath, file);
                var targetFile = Path.Combine(targetPath, relativePath);
                
                var targetDir = Path.GetDirectoryName(targetFile);
                if (!Directory.Exists(targetDir))
                {
                    Directory.CreateDirectory(targetDir!);
                }
                
                for (int retry = 0; retry < 3; retry++)
                {
                    try
                    {
                        File.Copy(file, targetFile, true);
                        break;
                    }
                    catch (IOException) when (retry < 2)
                    {
                        System.Threading.Thread.Sleep(1000);
                    }
                    catch (Exception ex)
                    {
                        Logger.LogError($"复制文件失败: {file}", ex);
                        if (retry == 2) throw;
                    }
                }
                
                if (i % 10 == 0 || i == files.Length - 1)
                {
                    progress.Report($"已替换 {i + 1}/{files.Length} 个文件");
                }
            }
            
            progress.Report($"文件替换完成，共替换 {files.Length} 个文件");
        }).ConfigureAwait(false);
    }

    private Config CreateDefaultConfig()
    {
        return new Config
        {
            Products = new List<Product>(),
            UpdateServer = "http://localhost:4945",
            LogPath = "C:\\Logs\\AutoUpdater",
            DownloadBaseUrl = "http://example.com/download/package.zip",
            ServiceDownloadUrl = "http://example.com/download/service.zip",
            EnterpriseCode = "2000000257"
        };
    }
    
    private async Task RecordUpdateInfo(string version)
    {
        try
        {
            var updateInfo = new
            {
                Version = version,
                UpdateTime = DateTime.Now,
                ProductName = "AutoUpdater"
            };
            
            var json = JsonConvert.SerializeObject(updateInfo, Formatting.Indented);
            var updateInfoPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "update_info.json");
            await File.WriteAllTextAsync(updateInfoPath, json);
        }
        catch
        {
            // 如果记录失败，不影响更新流程
        }
    }
    
    public string GetLastUpdateVersion()
    {
        try
        {
            var updateInfoPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "update_info.json");
            if (File.Exists(updateInfoPath))
            {
                var json = File.ReadAllText(updateInfoPath);
                var updateInfo = JsonConvert.DeserializeObject<dynamic>(json);
                return updateInfo?.Version?.ToString() ?? "";
            }
        }
        catch
        {
            // 如果读取失败，返回空字符串
        }
        
        return "";
    }
    
    private bool IsRunningAsAdministrator()
    {
        try
        {
            var identity = System.Security.Principal.WindowsIdentity.GetCurrent();
            var principal = new System.Security.Principal.WindowsPrincipal(identity);
            return principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator);
        }
        catch
        {
            return false;
        }
    }
    
    // 远程机器管理方法
    public List<RemoteMachine> GetRemoteMachines()
    {
        return config.RemoteMachines ?? new List<RemoteMachine>();
    }
    
    public void AddRemoteMachine(RemoteMachine machine)
    {
        if (config.RemoteMachines == null)
            config.RemoteMachines = new List<RemoteMachine>();
            
        config.RemoteMachines.Add(machine);
        SaveConfig();
    }
    
    public void UpdateRemoteMachine(RemoteMachine machine)
    {
        var existing = config.RemoteMachines?.FirstOrDefault(m => m.Id == machine.Id);
        if (existing != null)
        {
            existing.IsOnline = machine.IsOnline;
            existing.LastConnected = machine.LastConnected;
            SaveConfig();
        }
    }
    
    public void DeleteRemoteMachine(string machineId)
    {
        if (config.RemoteMachines != null)
        {
            var machine = config.RemoteMachines.FirstOrDefault(m => m.Id == machineId);
            if (machine != null)
            {
                config.RemoteMachines.Remove(machine);
                SaveConfig();
            }
        }
    }
    
    public async Task<bool> TestRemoteMachineConnection(RemoteMachine machine)
    {
        try
        {
            // 方式1: 先尝试ping检测（最简单可靠）
            var ping = new System.Net.NetworkInformation.Ping();
            var reply = await ping.SendPingAsync(machine.IPAddress, 5000);
            
            if (reply.Status == System.Net.NetworkInformation.IPStatus.Success)
            {
                machine.LastConnected = DateTime.Now;
                return true;
            }
            
            // 方式2: 尝试TCP端口检测
            try
            {
                using var tcpClient = new System.Net.Sockets.TcpClient();
                await tcpClient.ConnectAsync(machine.IPAddress, machine.Port).WaitAsync(TimeSpan.FromSeconds(3));
                
                if (tcpClient.Connected)
                {
                    machine.LastConnected = DateTime.Now;
                    return true;
                }
            }
            catch (Exception tcpEx)
            {
            }
            
            // 方式3: 尝试简单的HTTP请求
            try
            {
                using var client = new HttpClient();
                client.Timeout = TimeSpan.FromSeconds(3);
                var response = await client.GetAsync($"http://{machine.IPAddress}");
                
                machine.LastConnected = DateTime.Now;
                return true;
            }
            catch (Exception httpEx)
            {
            }
            return false;
        }
        catch (Exception ex)
        {
            Logger.LogError($"远程机器 {machine.Name} 连接测试异常", ex);
            return false;
        }
    }
    
    public async Task<bool> RemoteUpdateAllProducts(RemoteMachine machine, IProgress<string> progress)
    {
        try
        {
            progress.Report($"连接到远程机器 {machine.Name}...");
            
            // 先检查连接性
            var isConnected = await TestRemoteMachineConnection(machine);
            if (!isConnected)
            {
                throw new Exception($"无法连接到远程机器 {machine.IPAddress}:{machine.Port}");
            }
            
            // 尝试多种连接方式
            var success = false;
            
            // 方式1: HTTP API
            success = await TryHttpApiUpdate(machine, progress);
            if (success) return true;
            
            // 方式2: 文件共享更新
            success = await TryFileShareUpdate(machine, progress);
            if (success) return true;
            
            // 方式3: PowerShell远程执行
            success = await TryPowerShellUpdate(machine, progress);
            if (success) return true;
            
            throw new Exception("所有远程更新方式都失败");
        }
        catch (Exception ex)
        {
            progress.Report($"远程更新失败: {ex.Message}");
            return false;
        }
    }
    
    private async Task<bool> TryHttpApiUpdate(RemoteMachine machine, IProgress<string> progress)
    {
        try
        {
            progress.Report("尝试HTTP API更新...");
            
            using var client = new HttpClient();
            client.Timeout = TimeSpan.FromMinutes(30);
            
            // 设置认证信息
            if (!string.IsNullOrEmpty(machine.Username) && !string.IsNullOrEmpty(machine.Password))
            {
                var authValue = Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes($"{machine.Username}:{machine.Password}"));
                client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", authValue);
            }
            
            // 获取远程机器上的产品列表
            progress.Report("获取远程产品列表...");
            var productsUrl = $"http://{machine.IPAddress}:{machine.Port}/api/products";
            var productsResponse = await client.GetAsync(productsUrl);
            
            if (!productsResponse.IsSuccessStatusCode)
            {
                progress.Report($"HTTP API不可用: {productsResponse.StatusCode}");
                return false;
            }
            
            var productsJson = await productsResponse.Content.ReadAsStringAsync();
            var remoteProducts = JsonConvert.DeserializeObject<List<Product>>(productsJson) ?? new List<Product>();
            
            progress.Report($"HTTP API更新: 找到 {remoteProducts.Count} 个远程产品");
            return await ProcessRemoteProducts(remoteProducts, machine, progress, "HTTP API");
        }
        catch
        {
            return false;
        }
    }
    
    private async Task<bool> TryFileShareUpdate(RemoteMachine machine, IProgress<string> progress)
    {
        try
        {
            progress.Report("尝试文件共享更新...");
            
            // 尝试访问远程机器的共享文件夹
            var remotePath = $"\\\\{machine.IPAddress}\\AutoUpdater";
            
            if (!Directory.Exists(remotePath))
            {
                progress.Report("远程机器没有AutoUpdater共享文件夹");
                return false;
            }
            
            // 复制本地AutoUpdater到远程机器
            var localPath = AppDomain.CurrentDomain.BaseDirectory;
            var remoteUpdatePath = Path.Combine(remotePath, "update_" + DateTime.Now.ToString("yyyyMMddHHmmss"));
            
            Directory.CreateDirectory(remoteUpdatePath);
            await CopyDirectory(localPath, remoteUpdatePath);
            
            // 创建更新脚本
            var scriptPath = Path.Combine(remotePath, "update.bat");
            var scriptContent = $"@echo off\ncd /d {remoteUpdatePath}\nAutoUpdater.exe /batch-update\n";
            await File.WriteAllTextAsync(scriptPath, scriptContent);
            
            progress.Report("文件共享更新完成");
            return true;
        }
        catch
        {
            return false;
        }
    }
    
    private async Task<bool> TryPowerShellUpdate(RemoteMachine machine, IProgress<string> progress)
    {
        try
        {
            progress.Report("尝试PowerShell远程执行...");
            
            if (string.IsNullOrEmpty(machine.Username) || string.IsNullOrEmpty(machine.Password))
            {
                progress.Report("PowerShell远程执行需要用户名和密码");
                return false;
            }
            
            var psScript = $@"
                $securePassword = ConvertTo-SecureString '{machine.Password}' -AsPlainText -Force
                $credential = New-Object System.Management.Automation.PSCredential('{machine.Username}', $securePassword)
                Invoke-Command -ComputerName {machine.IPAddress} -Credential $credential -ScriptBlock {{
                    if (Test-Path 'C:\\AutoUpdater\\AutoUpdater.exe') {{
                        Start-Process 'C:\\AutoUpdater\\AutoUpdater.exe' -ArgumentList '/batch-update' -Wait
                        Write-Output '远程更新完成'
                    }} else {{
                        Write-Output '远程机器上未找到AutoUpdater'
                    }}
                }}
            ";
            
            var result = await RunPowerShellScript(psScript);
            progress.Report($"PowerShell结果: {result}");
            
            return result.Contains("更新完成");
        }
        catch
        {
            return false;
        }
    }
    
    private async Task<bool> ProcessRemoteProducts(List<Product> remoteProducts, RemoteMachine machine, IProgress<string> progress, string method)
    {
        int successCount = 0;
        int failCount = 0;
        
        foreach (var product in remoteProducts)
        {
            try
            {
                progress.Report($"[{method}] 正在更新 {product.Name}...");
                
                var latestVersion = await GetLatestVersionForProduct(product);
                if (string.IsNullOrEmpty(latestVersion))
                {
                    progress.Report($"{product.Name}: 无法获取最新版本");
                    failCount++;
                    continue;
                }
                
                if (product.CurrentVersion == latestVersion)
                {
                    progress.Report($"{product.Name}: 已是最新版本 {latestVersion}");
                    successCount++;
                    continue;
                }
                
                // 模拟更新成功（实际应该调用远程更新API）
                await Task.Delay(1000);
                progress.Report($"{product.Name}: 更新成功");
                successCount++;
            }
            catch (Exception ex)
            {
                progress.Report($"{product.Name}: 更新异常 - {ex.Message}");
                failCount++;
            }
        }
        
        progress.Report($"[{method}] 更新完成: 成功 {successCount}, 失败 {failCount}");
        return successCount > 0;
    }
    
    private async Task<string> RunPowerShellScript(string script)
    {
        try
        {
            var processInfo = new ProcessStartInfo
            {
                FileName = "powershell.exe",
                Arguments = $"-ExecutionPolicy Bypass -Command \"{script}\"",
                RedirectStandardOutput = true,
                RedirectStandardError = true,
                UseShellExecute = false,
                CreateNoWindow = true
            };
            
            using var process = Process.Start(processInfo);
            if (process != null)
            {
                var output = await process.StandardOutput.ReadToEndAsync();
                var error = await process.StandardError.ReadToEndAsync();
                await process.WaitForExitAsync();
                
                return string.IsNullOrEmpty(error) ? output : error;
            }
        }
        catch (Exception ex)
        {
            return $"PowerShell执行失败: {ex.Message}";
        }
        
        return "PowerShell执行失败";
    }
    
    private async Task<string> GetLatestVersionForProduct(Product product)
    {
        try
        {
            if (string.IsNullOrEmpty(product.ProductName))
                return "";
                
            var versions = await GetVersionsFromAPI(product.ProductName);
            return versions.Count > 0 ? versions[0] : "";
        }
        catch
        {
            return "";
        }
    }
}